<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Support\Facades\Log;
use Illuminate\Routing\Controller as BaseController;

class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    public function success($data = [], $msg = 'success')
    {
        return response()->json([
            'code' => 200,
            'msg' => $msg,
            'data' => $data
        ]);
    }

    public function error($msg = 'error', $data = [])
    {
        return response()->json([
            'code' => 400,
            'msg' => $msg,
            'data' => $data
        ]);
    }


    const RADIUS_COPPER = 300; // 铜币初始化半径
    const RADIUS_SILVER = 1000; // 银币初始化半径
    /**
     * 在给定圆环范围内随机生成一个点
     * 适用于硬币初始化
     */
    public function generateRandomPointInCircle($centerLat, $centerLng, $radius)
    {
        $randomAngle = mt_rand() / mt_getrandmax() * 2 * M_PI; // 随机角度
        $randomRadius = sqrt(mt_rand() / mt_getrandmax()) * $radius; // 随机半径（平方根确保均匀分布）

        $deltaLat = ($randomRadius / 111000) * cos($randomAngle); // 纬度变化
        $deltaLng = ($randomRadius / 111000) * sin($randomAngle) / cos(deg2rad($centerLat)); // 经度变化

        return [
            'lat' => $centerLat + $deltaLat,
            'lng' => $centerLng + $deltaLng
        ];
    }

    /**
     * 随机生成下一个圆心的位置，确保新的圆环满足以下约束：
     * 1. 新圆心在当前圆环范围内
     * 2. 新圆包含真实宝藏位置
     */
    public function generateNextCircleCenterWithConstraints($prevLat, $prevLng, $prevRadius, $newRadius, $treasure)
    {
        do {
            // 在上一层圆环内随机生成一个点作为新的圆心
            $randomPoint = $this->generateRandomPointInCircle($prevLat, $prevLng, $prevRadius);

            // 计算新圆心到真实宝藏的距离
            $distanceToTreasure = $this->haversine($randomPoint['lat'], $randomPoint['lng'], $treasure['lat'], $treasure['lng']);
            // 计算新圆心到上一层圆心的距离
            $distanceToPrevCenter = $this->haversine($randomPoint['lat'], $randomPoint['lng'], $prevLat, $prevLng);
        } while (
            $distanceToTreasure > $newRadius || // 确保真实宝藏在新圆环内
            $distanceToPrevCenter > ($prevRadius - $newRadius) // 确保新圆心在上一层圆环内
        );

        return $randomPoint;
    }

    /**
     * 计算两点之间的距离（Haversine公式）
     */
    private function haversine($lat1, $lng1, $lat2, $lng2)
    {
        $earthRadius = 6371000; // 地球半径（单位：米）
        $dLat = deg2rad($lat2 - $lat1);
        $dLng = deg2rad($lng2 - $lng1);

        $a = sin($dLat / 2) * sin($dLat / 2) +
            cos(deg2rad($lat1)) * cos(deg2rad($lat2)) *
            sin($dLng / 2) * sin($dLng / 2);

        $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
        return $earthRadius * $c;
    }

    /**
     * 根据真实经纬度，生成正六边形的经纬度数组
     * @param sideLength 六边形边长
     * @return Array
     */
    function generateHexagon($latitude, $longitude, $sideLength) {
        // 地球半径（单位：米）
        $earthRadius = 6378137;
    
        // 计算每个顶点的角度（以北为起点，顺时针方向）
        $angles = [0, 60, 120, 180, 240, 300];
        $hexagonCoordinates = [];
    
        foreach ($angles as $angle) {
            // 将角度转为弧度
            $angleRad = deg2rad($angle);
    
            // 计算顶点的经纬度
            $latOffset = ($sideLength / $earthRadius) * cos($angleRad);
            $lngOffset = ($sideLength / ($earthRadius * cos(deg2rad($latitude)))) * sin($angleRad);
    
            // 顶点的纬度和经度
            $vertexLat = $latitude + rad2deg($latOffset);
            $vertexLng = $longitude + rad2deg($lngOffset);
    
            // 添加到结果数组
            $hexagonCoordinates[] = ['latitude' => $vertexLat, 'longitude' => $vertexLng];
        }
    
        // 返回六边形坐标数组
        return $hexagonCoordinates;
    }
}
